package com.qqt.csr.archive.batch.task.etl.tasklet;

import cn.hutool.json.JSONUtil;
import com.qqt.csr.archive.batch.task.constants.ParamConstant;
import com.qqt.csr.archive.entity.reader.CsrImAccount;
import com.qqt.csr.archive.entity.reader.SmartConversation;
import com.qqt.csr.archive.entity.reader.item.AccountExtItem;
import com.qqt.csr.archive.enums.SourceType;
import com.qqt.csr.archive.service.CsrImAccountService;
import com.qqt.csr.archive.service.SmartConversationService;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

/**
 * @Author: yang hao
 * @Date: 2024/12/2 11:22
 * @Description: 账户数据预处理
 **/
@Slf4j
@Component
@SuppressWarnings("all")
public class AccountPreTasklet implements Tasklet {

    @Autowired
    private SmartConversationService smartConversationService;
    @Autowired
    private CsrImAccountService csrImAccountService;

    /**
     * 以 step contribution 的形式给定当前上下文，执行任何必要的操作在 transaction 中处理此单元。Implementations 返回
     * {@link RepeatStatus#FINISHED} （如果已完成）。如果没有，他们将返回
     * {@link RepeatStatus#CONTINUABLE} 中。失败时引发异常。
     *
     * @param contribution mutable 状态以更新当前步骤执行
     * @param context 在调用之间共享的属性，但不在重新启动之间共享的属性
     * @return {@link RepeatStatus} 指示处理是否可继续。返回 {@code null} 将被解释为 {@link RepeatStatus#FINISHED}
     */
    @Override
    public RepeatStatus execute(@NonNull StepContribution contribution, @NonNull ChunkContext context) throws Exception {
        // 解析任务入参
        StepExecution execution = contribution.getStepExecution();
        JobParameters parameters = execution.getJobParameters();
        String conversationJson = parameters.getString(ParamConstant.CONVERSATION_IDS);
        String source = parameters.getString(ParamConstant.SOURCE);
        List<String> conversationIds = JSONUtil.toList(conversationJson, String.class);
        SourceType sourceType = SourceType.matchIgnoreCase(source);
        // 仅处理智能客服侧账户问题
        if (SourceType.SMART.equals(sourceType)) {
            List<SmartConversation> conversations = smartConversationService.getByIds(conversationIds);
            if (conversations == null || conversations.isEmpty()) {
                throw new RuntimeException("会话数据不存在:" + conversationIds);
            }
            List<CsrImAccount> accounts = conversations.stream()
                    .map(this::createAccount)
                    .filter(Objects::nonNull)
                    .distinct()
                    .toList();
            csrImAccountService.saveBatchIfNotExist(accounts);
        }
        return RepeatStatus.FINISHED;
    }

    /**
     * 创建账户
     * @param conversation {@link SmartConversation} 智能客服会话
     * @return {@link CsrImAccount} 账户
     */
    private CsrImAccount createAccount(SmartConversation conversation) {
        // 获取访客、机器人id
        String visitorId = conversation.getVisitorId();
        String robotId = String.valueOf(conversation.getRebotId());
        // 查询访客和机器人账户信息
        CsrImAccount visitor = csrImAccountService.getAccountByUserId(visitorId, 0, conversation.getChannelId().toString());
        CsrImAccount robot = csrImAccountService.getAccountByUserId(robotId, 2, conversation.getChannelId().toString());
        // 若账户不存在，则创建账户
        if (visitor == null) {
            String userId = String.format("CSR%s-%s", conversation.getChannelId(), conversation.getVisitorId());
            return createAccount(userId, conversation.getVisitorName(), null, conversation.getVisitorId(), "0");
        }
        if (robot == null) {
            String userId = String.format("ROBOT%s", conversation.getRebotId());
            return createAccount(userId, conversation.getRebotName(), conversation.getRebotId().toString(), null, "2");
        }
        return null;
    }

    /**
     * 创建账户
     * @param usedId {@link String} 用户id
     * @param userName {@link String} 用户名
     * @param userType {@link String} 用户类型
     * @return {@link CsrImAccount} 账户
     */
    private CsrImAccount createAccount(String usedId, String userName, String csId, String uId, String userType) {
        CsrImAccount csAccount = new CsrImAccount();
        AccountExtItem extItem = AccountExtItem.builder()
                .csId(csId)
                .uId(uId)
                .userType(userType)
                .build();
        csAccount.setAccountUserId(usedId);
        csAccount.setAccountName(userName);
        csAccount.setExtJson(JSONUtil.toJsonStr(extItem));
        return csAccount;
    }
}
